using System;
using System.Xml;

using DesignByContract;

using Outcoding.GraphGenerator.Util.Logging;

namespace Outcoding.GraphGenerator.Composition {
    public class BuilderDirector {

        private XmlDocument mDocument;

        public BuilderDirector() {
        }

        public XmlDocument Document {
            get {
                return mDocument;
            }
            set {
                mDocument = value;
            }
        }

        public void Build(BuilderBase builder, object parent) {
            Check.Ensure(builder != null, "Concrete and valid builder must be supplied");
            if (mDocument != null) {
                try {
                    builder.SelectNode(mDocument);
                    builder.Compose();
                    if (parent != null)
                        builder.AppendToParent(parent);
                } catch (PreconditionException preExc) {
                    LogManager.Instance.LogError("Error on BuilderDirector", preExc);
                    throw;
                } catch (PostconditionException postExc) {
                    LogManager.Instance.LogError("Error on BuilderDirector", postExc);
                    throw;
                } catch (NotImplementedException notImpExc) {
                    //do nothing
                } catch (Exception exc) {
                    LogManager.Instance.LogError("Error on BuilderDirector", exc);
                }
            } else
                throw new ArgumentNullException("Cannot build without a valid XmlDocument");
        }

        public void Build(BuilderBase builder, XmlDocument document, object parent) {
            Check.Ensure(builder != null, "Concrete and valid builder must be supplied");

            try {
                builder.SelectNode(document);
                builder.Compose();
                if(parent != null)
                    builder.AppendToParent(parent);
            }catch(PreconditionException preExc){
                LogManager.Instance.LogError("Error on BuilderDirector", preExc);
                throw;
            } catch (PostconditionException postExc) {
                LogManager.Instance.LogError("Error on BuilderDirector", postExc);
                throw;
            }catch(NotImplementedException notImpExc){
                //do nothing
            }catch(Exception exc){
                LogManager.Instance.LogError("Error on BuilderDirector", exc);
            }
        }

        public void Build(BuilderBase builder, XmlNode node, object parent) {
            Check.Ensure(builder != null, "Concrete and valid builder must be supplied");

            try {
                //builder.SelectNode(document);
                builder.Compose(node);
                if (parent != null)
                    builder.AppendToParent(parent);
            } catch (PreconditionException preExc) {
                LogManager.Instance.LogError("Error on BuilderDirector", preExc);
                throw;
            } catch (PostconditionException postExc) {
                LogManager.Instance.LogError("Error on BuilderDirector", postExc);
                throw;
            } catch (NotImplementedException notImpExc) {
                //do nothing
            } catch (Exception exc) {
                LogManager.Instance.LogError("Error on BuilderDirector", exc);
            }
        }
    }
}
